#include "Space.h"
#include "Drop.h"
#include "Dot.h"
#include "Painter.h"
#include "Wave.h"


#include <cstdlib>
#include <iostream>

/**
 * 
 * @param wave
 * @return 
 */
void Space::spreadWave(Wave &wave)
{
    std::deque< Drop >::iterator dropsIterator;
    
    for (dropsIterator = drops.begin(); dropsIterator != drops.end(); dropsIterator++) {
        if (dropsIterator->hasCrossing(wave)) {
            RefractionWaves waves = dropsIterator->refraction(wave);
            addWave(waves.first);
            addWave(waves.second);
            addWave(waves.third);
            break;
        }
    }
    
    addWave(wave);
}

/**
 * 
 * @param filename
 * @return 
 */
void Space::draw(const char * filename)
{
    unsigned max_drop_x = 0;
    unsigned max_drop_y = 0;
    
    std::deque< Drop >::iterator dropsIterator;
    
    for (dropsIterator = drops.begin(); dropsIterator != drops.end(); dropsIterator++) {
        unsigned current_drop_x = (dropsIterator->getPosition().getX() + dropsIterator->getRadius()) * 2.0;
        unsigned current_drop_y = (dropsIterator->getPosition().getY() + dropsIterator->getRadius()) * 2.0;
        
        if (current_drop_x > max_drop_x) {
            max_drop_x = current_drop_x;
        }
        
        if (current_drop_y > max_drop_y) {
            max_drop_y = current_drop_y;
        }
    }
    
    Painter painter(filename, max_drop_x, max_drop_y);
    
    Color grey(77, 77, 77);
    
    for (dropsIterator = drops.begin(); dropsIterator != drops.end(); dropsIterator++) {
        painter.drawCircle(dropsIterator->getPosition(), dropsIterator->getRadius(), grey);
    }
    
    std::deque< Wave >::iterator wavesIterator;
    
    for (wavesIterator = waves.begin(); wavesIterator != waves.end(); wavesIterator++) {
        if (wavesIterator->getHasEnding()) {
            painter.drawLine(wavesIterator->getSource(), wavesIterator->getEnding(), Color(wavesIterator->getLength()));    
        }
        else {
            unsigned endX = max_drop_x;
            unsigned endY = wavesIterator->getSource().getY() + wavesIterator->getTangent() * (endX - wavesIterator->getSource().getX());
            
            if ( endY > max_drop_y ) {
                endY = max_drop_y;
                endX = (endY - wavesIterator->getSource().getY()) / wavesIterator->getTangent() + wavesIterator->getSource().getX();
            }
            
            painter.drawLine(wavesIterator->getSource(), Dot(endX, endY), Color(wavesIterator->getLength()));
        }
    }
    
    painter.finish();
}
